package ace.module.oauth2.server.core.impl.service.impl;

import ace.module.oauth2.server.core.impl.converter.Oauth2RegisteredClientFromRegisteredClientConverter;
import ace.module.oauth2.server.core.impl.converter.Oauth2RegisteredClientToRegisteredClientConverter;
import ace.module.oauth2.server.core.impl.dao.entity.Oauth2RegisteredClient;
import ace.module.oauth2.server.core.impl.manager.Oauth2RegisteredClientManager;
import ace.module.oauth2.server.core.impl.manager.cache.Oauth2RegisteredClientCacheManager;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.server.authorization.client.JdbcRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository;
import org.springframework.stereotype.Component;

/**
 * @author caspar
 * @date 2024/2/21 18:54 {@link JdbcRegisteredClientRepository}
 */
@Slf4j
@AllArgsConstructor
@Component
public class RegisteredClientRepositoryImpl implements RegisteredClientRepository {
  private final Oauth2RegisteredClientManager oauth2RegisteredClientManager;
  private final Oauth2RegisteredClientCacheManager oauth2RegisteredClientCacheManager;
  private final Oauth2RegisteredClientFromRegisteredClientConverter
      oauth2RegisteredClientFromRegisteredClientConverter;
  private final Oauth2RegisteredClientToRegisteredClientConverter
      oauth2RegisteredClientToRegisteredClientConverter;

  @Override
  public void save(RegisteredClient registeredClient) {
    Oauth2RegisteredClient oldOauth2RegisteredClient =
        this.oauth2RegisteredClientCacheManager.getById(registeredClient.getId());
    Oauth2RegisteredClient oauth2RegisteredClient =
        this.convertWithOldData(registeredClient, oldOauth2RegisteredClient);
    this.oauth2RegisteredClientCacheManager.clear(oauth2RegisteredClient);
    if (oldOauth2RegisteredClient == null) {
      this.oauth2RegisteredClientManager.add(oauth2RegisteredClient);
    } else {
      this.oauth2RegisteredClientManager.modify(oauth2RegisteredClient);
    }
  }

  @Override
  public RegisteredClient findById(String id) {
    Oauth2RegisteredClient oAuth2RegisteredClient =
        this.oauth2RegisteredClientCacheManager.getById(id);
    RegisteredClient registeredClient =
        this.oauth2RegisteredClientToRegisteredClientConverter.convert(oAuth2RegisteredClient);
    return registeredClient;
  }

  @Override
  public RegisteredClient findByClientId(String clientId) {
    Oauth2RegisteredClient oAuth2RegisteredClient =
        this.oauth2RegisteredClientCacheManager.getByClientId(clientId);
    RegisteredClient registeredClient =
        this.oauth2RegisteredClientToRegisteredClientConverter.convert(oAuth2RegisteredClient);
    return registeredClient;
  }

  private Oauth2RegisteredClient convertWithOldData(
      RegisteredClient registeredClient, Oauth2RegisteredClient oldOauth2RegisteredClient) {
    Oauth2RegisteredClient oauth2RegisteredClient =
        this.oauth2RegisteredClientFromRegisteredClientConverter.convert(registeredClient);
    if (oldOauth2RegisteredClient != null) {
      oauth2RegisteredClient.setCreateTime(oldOauth2RegisteredClient.getCreateTime());
      oauth2RegisteredClient.setRowVersion(oldOauth2RegisteredClient.getRowVersion());
      oauth2RegisteredClient.setDeleteFlag(oldOauth2RegisteredClient.getDeleteFlag());
    }
    return oauth2RegisteredClient;
  }
}
